package bcontractor.partialmeet;

import static bcontractor.base.SetUtils.intersection;

import java.util.Set;

import bcontractor.api.ContractionOperator;
import bcontractor.api.Sentence;
import bcontractor.api.SentenceSet;

/**
 * Implementation of the contraction operation using partial meets between
 * remainder sets
 * 
 * @author lundberg
 * 
 * @param <S>
 */
public class PartialMeetContractionOperator<S extends Sentence<S>> implements ContractionOperator<S> {

    private final RemainderSetOperator<S> remainder;

    private final SelectionFunction<S> selection;

    /**
     * Construtor
     * 
     * @param remainder
     *            remainder
     * @param selection
     *            selection
     */
    public PartialMeetContractionOperator(RemainderSetOperator<S> remainder, SelectionFunction<S> selection) {
        this.remainder = remainder;
        this.selection = selection;
    }

    /**
     * {@inheritDoc}
     */
    public SentenceSet<S> eval(SentenceSet<S> base, S sentence) {
        return intersection(this.selection(this.remainder(base, sentence)));
    }

    /**
     * Invokes the remainder set operator
     * 
     * @param base
     *            base
     * @param sentence
     *            sentence
     * @return remainder set
     */
    private RemainderSet<S> remainder(SentenceSet<S> base, S sentence) {
        return this.remainder.eval(base, sentence);
    }

    /**
     * Invokes the selection function
     * 
     * @param remainder
     *            remainder
     * @return selected elements from remainder set
     */
    private Set<SentenceSet<S>> selection(RemainderSet<S> remainder) {
        return this.selection.eval(remainder);
    }
}
